<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Plugin
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-23
 ***********************************************************************/
if(defined("PLUGIN_DEBUGER_ACTION"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("PLUGIN_DEBUGER_ACTION", true);

class CActionDebugger extends CAction
{
    protected $m_debugMsg   = array();
    
    public function DoIndex(CRequest & $request)
    {
        set_error_handler(array($this, "HookPhpError"));
        CLog::Get()->Level(CLog::LEVEL_NOTE);
        
        $args       = new ELogArgs('');
        foreach( CLog::Get()->GetLog(CLog::LEVEL_FATAL) as $args->message ){
            $this->CallBackLogFatal($args);
        }
        foreach( CLog::Get()->GetLog(CLog::LEVEL_ERROR) as $args->message ){
            $this->CallBackLogError($args);
        }
        foreach( CLog::Get()->GetLog(CLog::LEVEL_WARING) as $args->message ){
            $this->CallBackLogWarning($args);
        }
        foreach( CLog::Get()->GetLog(CLog::LEVEL_NOTE) as $args->message ){
            $this->CallBackLogNote($args);
        }
        unset($args);
        
        CLog::Get()->Subscribe(CLog::EVT_FATAL, new CEventCallBack('CallBackLogFatal', $this));
        CLog::Get()->Subscribe(CLog::EVT_ERROR, new CEventCallBack('CallBackLogError', $this));
        CLog::Get()->Subscribe(CLog::EVT_WARNING, new CEventCallBack('CallBackLogWarning', $this));
        CLog::Get()->Subscribe(CLog::EVT_NOTE, new CEventCallBack('CallBackLogNote', $this));
        CEngine::Get()->Subscribe(CEngine::EVT_PRE_SHUTDOWN, new CEventCallBack('EnginePreShutdown', $this));
        CEngine::Get()->Subscribe(CEngine::EVT_POST_SHUTDOWN, new CEventCallBack('EnginePostShutdown', $this));
        
        $this->SetLayout(null);
        
        $debugWinName = 'debug';
        $winMgr       = CWindowManager::Get();
        if( !$winMgr->HasInStorage($debugWinName) )
        {
            $window = $winMgr->GetRoot()->CreateWindow($debugWinName);
            $window->SetTitle('Debugger Window');
            $window->SetAlwayTop(true);
            $window->SetAlign('right top');
            $window->SetPosX(0);
            $window->SetPosY(0);
            $window->SetDraggable(true);
            $window->SetResizable(false);
            $window->SetHeight('auto');
            $window->SetWidth('50%');
            $window->SetMinHeight('0');
            $window->SetBorderStyle('0');
            $window->SetTitlebar(false);
            $window->SetWinStyle(CWindow::WS_MIN|CWindow::WS_MAX);
            
            $this->GetView()->SetWindow($debugWinName, false);
            $this->GetView()->AddContent($window->Render(), true);
            
            return true;
        }
        
        return false;
    }
    
    public function DoRender(CRequest & $request)
    {
        CLog::Get()->Note('The page should be shutdown.');
        
        $logContent = '$(function(){'.
                //'$(\'#debug-tabs\').tabs(\'select\', 1);'.
                '$(\'#debug-tabs-logs\').append(\''.
                CStringHelper::ToJS(implode('',$this->m_debugMsg)).'<br>\');'.
                'var last = 0; var anim = setInterval(function(){$(\'#debug-tabs-logs\').scrollTop($(\'#debug-tabs-logs\').scrollTop()+10);'.
                'if($(\'#debug-tabs-logs\').scrollTop() == last){clearInterval(anim);}else{last=$(\'#debug-tabs-logs\').scrollTop()}}, 10);});';
                //'$(\'#window_debug\').scrollTop($(\'#window_debug\').scrollTop()+10000);});';

        $this->GetView()->AddScript($logContent);
    }
    
    public function CallBackLogFatal(ELogArgs & $evtArgs)
    {
        $content    = '<li>[ Fatal ] '.$evtArgs->message.'<br></li>';
        $this->m_debugMsg[] = $content;
    }
    
    public function CallBackLogError(ELogArgs & $evtArgs)
    {
        $content    = '<li>[ Error ] '.$evtArgs->message.'<br></li>';
        $this->m_debugMsg[] = $content;
    }
    
    public function CallBackLogWarning(ELogArgs & $evtArgs)
    {
        $content    = '<li>[Warning] '.$evtArgs->message.'<br></li>';
        $this->m_debugMsg[] = $content;
    }
    
    public function CallBackLogNote(ELogArgs & $evtArgs)
    {
        $content    = '<li>[  Note ] '.$evtArgs->message.'<br></li>';
        $this->m_debugMsg[] = $content;
    }
    
    public function EnginePreShutdown(CEventArgs & $evtArgs)
    {
        CContext::Get()->GetController()->Forward($this->GetName(), 'Render');
        CLog::Get()->Clear();
    }
    
    public function EnginePostShutdown(CEventArgs & $evtArgs)
    {
        
    }
    
    public function HookPhpError($errno, $errstr, $errfile, $errline)
    {
        if (($errno & error_reporting()) == 0)
        {
          return false;
        }
        $msg = sprintf('PHP sent a "%%s" error at %s line %s (%s)', $errfile, $errline, $errstr);
        switch ($errno) 
        {
            case E_CORE_ERROR:
            case E_COMPILE_ERROR:
                $msg = sprintf($msg, 'Fatal Error');
                CLog::Get()->Fatal($msg);
            break;
            case E_PARSE:
            case E_ERROR:
            case E_USER_ERROR:
            case E_RECOVERABLE_ERROR:
                $msg = sprintf($msg, 'Error');
                CLog::Get()->Error($msg);
            break;
            case E_WARNING:
            case E_CORE_WARNING:
            case E_USER_WARNING:
            case E_COMPILE_WARNING:
                $msg = sprintf($msg, 'Warning');
                CLog::Get()->Warning($msg);
            break;
            case E_STRICT:
            case E_USER_NOTICE:
            default:
                 return;
            break;
        }
    }
}

?>
